Merge "Proper namespace handling for WikiImporter"
[lhc/web/wiklou.git] / includes / specials / SpecialImport.php
index 2a3ab64..9e9f8c0 100644 (file)
  * @ingroup SpecialPage
  */
 class SpecialImport extends SpecialPage {
+       private $sourceName = false;
        private $interwiki = false;
+       private $subproject;
+       private $fullInterwikiPrefix;
        private $namespace;
        private $rootpage = '';
        private $frompage = '';
@@ -44,17 +47,22 @@ class SpecialImport extends SpecialPage {
         */
        public function __construct() {
                parent::__construct( 'Import', 'import' );
-               $this->namespace = $this->getConfig()->get( 'ImportTargetNamespace' );
        }
 
        /**
         * Execute
         * @param string|null $par
+        * @throws PermissionsError
+        * @throws ReadOnlyError
         */
        function execute( $par ) {
                $this->setHeaders();
                $this->outputHeader();
 
+               $this->namespace = $this->getConfig()->get( 'ImportTargetNamespace' );
+
+               $this->getOutput()->addModules( 'mediawiki.special.import' );
+
                $user = $this->getUser();
                if ( !$user->isAllowedAny( 'import', 'importupload' ) ) {
                        throw new PermissionsError( 'import' );
@@ -94,7 +102,7 @@ class SpecialImport extends SpecialPage {
                $isUpload = false;
                $request = $this->getRequest();
                $this->namespace = $request->getIntOrNull( 'namespace' );
-               $sourceName = $request->getVal( "source" );
+               $this->sourceName = $request->getVal( "source" );
 
                $this->logcomment = $request->getText( 'log-comment' );
                $this->pageLinkDepth = $this->getConfig()->get( 'ExportMaxLinkDepth' ) == 0
@@ -105,30 +113,41 @@ class SpecialImport extends SpecialPage {
                $user = $this->getUser();
                if ( !$user->matchEditToken( $request->getVal( 'editToken' ) ) ) {
                        $source = Status::newFatal( 'import-token-mismatch' );
-               } elseif ( $sourceName == 'upload' ) {
+               } elseif ( $this->sourceName == 'upload' ) {
                        $isUpload = true;
                        if ( $user->isAllowed( 'importupload' ) ) {
                                $source = ImportStreamSource::newFromUpload( "xmlimport" );
                        } else {
                                throw new PermissionsError( 'importupload' );
                        }
-               } elseif ( $sourceName == "interwiki" ) {
+               } elseif ( $this->sourceName == "interwiki" ) {
                        if ( !$user->isAllowed( 'import' ) ) {
                                throw new PermissionsError( 'import' );
                        }
-                       $this->interwiki = $request->getVal( 'interwiki' );
-                       if ( !in_array( $this->interwiki, $this->getConfig()->get( 'ImportSources' ) ) ) {
+                       $this->interwiki = $this->fullInterwikiPrefix = $request->getVal( 'interwiki' );
+                       // does this interwiki have subprojects?
+                       $importSources = $this->getConfig()->get( 'ImportSources' );
+                       $hasSubprojects = array_key_exists( $this->interwiki, $importSources );
+                       if ( !$hasSubprojects && !in_array( $this->interwiki, $importSources ) ) {
                                $source = Status::newFatal( "import-invalid-interwiki" );
                        } else {
-                               $this->history = $request->getCheck( 'interwikiHistory' );
-                               $this->frompage = $request->getText( "frompage" );
-                               $this->includeTemplates = $request->getCheck( 'interwikiTemplates' );
-                               $source = ImportStreamSource::newFromInterwiki(
-                                       $this->interwiki,
-                                       $this->frompage,
-                                       $this->history,
-                                       $this->includeTemplates,
-                                       $this->pageLinkDepth );
+                               if ( $hasSubprojects ) {
+                                       $this->subproject = $request->getVal( 'subproject' );
+                                       $this->fullInterwikiPrefix .= ':' . $request->getVal( 'subproject' );
+                               }
+                               if ( $hasSubprojects && !in_array( $this->subproject, $importSources[$this->interwiki] ) ) {
+                                       $source = Status::newFatal( "import-invalid-interwiki" );
+                               } else {
+                                       $this->history = $request->getCheck( 'interwikiHistory' );
+                                       $this->frompage = $request->getText( "frompage" );
+                                       $this->includeTemplates = $request->getCheck( 'interwikiTemplates' );
+                                       $source = ImportStreamSource::newFromInterwiki(
+                                               $this->fullInterwikiPrefix,
+                                               $this->frompage,
+                                               $this->history,
+                                               $this->includeTemplates,
+                                               $this->pageLinkDepth );
+                               }
                        }
                } else {
                        $source = Status::newFatal( "importunknownsource" );
@@ -141,7 +160,7 @@ class SpecialImport extends SpecialPage {
                                array( 'importfailed', $source->getWikiText() )
                        );
                } else {
-                       $importer = new WikiImporter( $source->value );
+                       $importer = new WikiImporter( $source->value, $this->getConfig() );
                        if ( !is_null( $this->namespace ) ) {
                                $importer->setTargetNamespace( $this->namespace );
                        }
@@ -166,7 +185,7 @@ class SpecialImport extends SpecialPage {
                        $reporter = new ImportReporter(
                                $importer,
                                $isUpload,
-                               $this->interwiki,
+                               $this->fullInterwikiPrefix,
                                $this->logcomment
                        );
                        $reporter->setContext( $this->getContext() );
@@ -235,7 +254,8 @@ class SpecialImport extends SpecialPage {
                                        Xml::label( $this->msg( 'import-comment' )->text(), 'mw-import-comment' ) .
                                        "</td>
                                        <td class='mw-input'>" .
-                                       Xml::input( 'log-comment', 50, '',
+                                       Xml::input( 'log-comment', 50,
+                                               ( $this->sourceName == 'upload' ? $this->logcomment : '' ),
                                                array( 'id' => 'mw-import-comment', 'type' => 'text' ) ) . ' ' .
                                        "</td>
                                </tr>
@@ -299,7 +319,7 @@ class SpecialImport extends SpecialPage {
                                        Xml::openElement( 'table', array( 'id' => 'mw-import-table-interwiki' ) ) .
                                        "<tr>
                                        <td class='mw-label'>" .
-                                       Xml::label( $this->msg( 'import-interwiki-source' )->text(), 'interwiki' ) .
+                                       Xml::label( $this->msg( 'import-interwiki-sourcewiki' )->text(), 'interwiki' ) .
                                        "</td>
                                        <td class='mw-input'>" .
                                        Xml::openElement(
@@ -308,13 +328,63 @@ class SpecialImport extends SpecialPage {
                                        )
                        );
 
-                       foreach ( $importSources as $prefix ) {
-                               $selected = ( $this->interwiki === $prefix ) ? ' selected="selected"' : '';
-                               $out->addHTML( Xml::option( $prefix, $prefix, $selected ) );
+                       $needSubprojectField = false;
+                       foreach ( $importSources as $key => $value ) {
+                               if ( is_int( $key ) ) {
+                                       $key = $value;
+                               } elseif ( $value !== $key ) {
+                                       $needSubprojectField = true;
+                               }
+
+                               $attribs = array(
+                                       'value' => $key,
+                               );
+                               if ( is_array( $value ) ) {
+                                       $attribs['data-subprojects'] = implode( ' ', $value );
+                               }
+                               if ( $this->interwiki === $key ) {
+                                       $attribs['selected'] = 'selected';
+                               }
+                               $out->addHTML( Html::element( 'option', $attribs, $key ) );
                        }
 
                        $out->addHTML(
-                               Xml::closeElement( 'select' ) .
+                               Xml::closeElement( 'select' )
+                       );
+
+                       if ( $needSubprojectField ) {
+                               $out->addHTML(
+                                       Xml::openElement(
+                                               'select',
+                                               array( 'name' => 'subproject', 'id' => 'subproject' )
+                                       )
+                               );
+
+                               $subprojectsToAdd = array();
+                               foreach ( $importSources as $key => $value ) {
+                                       if ( is_array( $value ) ) {
+                                               $subprojectsToAdd = array_merge( $subprojectsToAdd, $value );
+                                       }
+                               }
+                               $subprojectsToAdd = array_unique( $subprojectsToAdd );
+                               sort( $subprojectsToAdd );
+                               foreach ( $subprojectsToAdd as $subproject ) {
+                                       $out->addHTML( Xml::option( $subproject, $subproject, $this->subproject === $subproject ) );
+                               }
+
+                               $out->addHTML(
+                                       Xml::closeElement( 'select' )
+                               );
+                       }
+
+                       $out->addHTML(
+                                       "</td>
+                               </tr>
+                               <tr>
+                                       <td class='mw-label'>" .
+                                       Xml::label( $this->msg( 'import-interwiki-sourcepage' )->text(), 'frompage' ) .
+                                       "</td>
+                                       <td class='mw-input'>" .
                                        Xml::input( 'frompage', 50, $this->frompage, array( 'id' => 'frompage' ) ) .
                                        "</td>
                                </tr>
@@ -365,7 +435,8 @@ class SpecialImport extends SpecialPage {
                                        Xml::label( $this->msg( 'import-comment' )->text(), 'mw-interwiki-comment' ) .
                                        "</td>
                                        <td class='mw-input'>" .
-                                       Xml::input( 'log-comment', 50, '',
+                                       Xml::input( 'log-comment', 50,
+                                               ( $this->sourceName == 'interwiki' ? $this->logcomment : '' ),
                                                array( 'id' => 'mw-interwiki-comment', 'type' => 'text' ) ) . ' ' .
                                        "</td>
                                </tr>
@@ -450,13 +521,14 @@ class ImportReporter extends ContextSource {
 
        /**
         * @param Title $title
-        * @param Title $origTitle
+        * @param ForeignTitle $foreignTitle
         * @param int $revisionCount
         * @param int $successCount
         * @param array $pageInfo
         * @return void
         */
-       function reportPage( $title, $origTitle, $revisionCount, $successCount, $pageInfo ) {
+       function reportPage( $title, $foreignTitle, $revisionCount,
+                       $successCount, $pageInfo ) {
                $args = func_get_args();
                call_user_func_array( $this->mOriginalPageOutCallback, $args );
 
@@ -485,7 +557,7 @@ class ImportReporter extends ContextSource {
                                $log->addEntry( 'upload', $title, $detail, array(), $this->getUser() );
                        } else {
                                $interwiki = '[[:' . $this->mInterwiki . ':' .
-                                       $origTitle->getPrefixedText() . ']]';
+                                       $foreignTitle->getFullText() . ']]';
                                $detail = $this->msg( 'import-logentry-interwiki-detail' )->numParams(
                                        $successCount )->params( $interwiki )->inContentLanguage()->text();
                                if ( $this->reason ) {
@@ -511,7 +583,7 @@ class ImportReporter extends ContextSource {
                                $page = WikiPage::factory( $title );
                                # Update page record
                                $page->updateRevisionOn( $dbw, $nullRevision );
-                               wfRunHooks(
+                               Hooks::run(
                                        'NewRevisionFromEditComplete',
                                        array( $page, $nullRevision, $latest, $this->getUser() )
                                );